home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power CD-ROM!! 8
/
Power CD-ROM 8.iso
/
prgmming
/
maxlib10
/
maxlib.ref
< prev
next >
Wrap
Text File
|
1994-10-14
|
80KB
|
2,267 lines
MAXLIB.REF
──────────────────────────────────────
Technical Reference for MAXLIB For PB
Copyright 1994 Brian McLaughlin
────────────────────────────────────────────
All Rights Reserved
TABLE OF CONTENTS
line number
INTRODUCTION ........................................ 93
SECTION ONE - MAXFiles Routines
MAXFiles Routines ................................. 116
ClearX ............................................ 184
ClipX ............................................. 228
CloseX ............................................ 271
EndX% ............................................. 308
ErrorCode% ........................................ 342
FlushX ............................................ 369
GetLineX$ ......................................... 411
GetLocX& .......................................... 469
GetPtrBase% ....................................... 503
GetStX ............................................ 545
GetX .............................................. 591
HandleX% .......................................... 659
InitMAXFiles ...................................... 687
KillX ............................................. 736
LoadX ............................................. 763
OpenX% ............................................ 810
PutStX ............................................ 892
PutX .............................................. 947
SaveLineX ......................................... 1026
SaveX ............................................. 1084
SetAccessCode ..................................... 1147
SetBufferSize ..................................... 1191
SetDiskFile ....................................... 1233
SetErrorCode ...................................... 1264
SetLocX ........................................... 1288
SetPtrBase ........................................ 1350
SizeX& ............................................ 1393
SECTION TWO - MAXArray Routines
MAXArray Routines .................................. 1430
ArrayInEMS ........................................ 1487
ArrayOutEMS ....................................... 1552
BytesFreeEMS& ..................................... 1620
ClearEMS .......................................... 1656
DimEMS% ........................................... 1691
EraseEMS .......................................... 1753
ErrorCode% ........................................ 1784
FileInEMS ......................................... 1814
FileOutEMS ........................................ 1878
HandlesEMS% ....................................... 1928
InEMS ............................................. 1958
InitMAXArray ...................................... 2009
LBoundEMS% ........................................ 2060
OutEMS ............................................ 2088
RedimEMS (requires 4.0 EMM driver) .............. 2134
SetErrorCode ...................................... 2187
UBoundEMS% ........................................ 2212
VersionEMS% ....................................... 2238
INTRODUCTION
This file (MAXLIB.REF) is the technical reference for MAXLIB For
PB. It contains a complete detailed description of each routine
in MAXLIB For PB, including its DECLARE statement, a list of
parameters passed and a description of how the routine works.
For further information about MAXLIB For PB (such as how it
handles errors) see the file MAXLIB.DOC.
To use MAXLIB For PB you must have a copy of the PowerBASIC 3.0b
compiler or later. I have tested MAXLIB For PB with the
PowerBASIC 3.0a release and found that because of bugs in that
compiler, MAXLIB For PB is not stable.
PowerBASIC is a trademark of PowerBASIC, Inc of Carmel,
California.
MAXFiles Routines
-----------------------------------------------------------------
MAXFiles can open or create files and store them in expanded
memory, where they can be accessed using methods similar to
those used for ordinary disk files. If MAXFiles fails to find
sufficient expanded memory, it will use disk space instead,
allowing you to write code that will work on machines with or
without EMS.
In order to use expanded memory, MAXFiles requires an EMM driver
that conforms to the LIM 4.0 EMS standard. When no EMM driver
is present, or when an EMM driver is present but it has a
version number lower than 4.0, MAXFiles will not use expanded
memory, but will use disk space instead.
The following is a list of MAXFiles routines along with their
closest counterparts in PowerBASIC:
OpenX% ................ OPEN (...FOR BINARY)
SetAccessCode ......... ACCESS LOCK/UNLOCK/READ/WRITE, etc.
CloseX ................ CLOSE# (close one open file)
ClearX ................ CLOSE (close all open files)
PutX .................. PUT (file statement)
GetX .................. GET (file statement)
PutStX ................ PUT$
GetStX ................ GET$
SaveX ................. BSAVE
LoadX ................. BLOAD
GetLineX$ ............. LINE INPUT# (file statement)
EndX% ................. EOF
GetLocX& .............. SEEK (as a function)
SetLocX ............... SEEK (as a statement)
SizeX& ................ LOF
KillX ................. KILL
FlushX ................ FLUSH
ErrorCode% ............ ERR
SetErrorCode .......... ERROR
SetPtrBase ............ OPTION BASE
MAXFiles also includes the following commands that have no exact
equivalent in BASIC:
InitMAXFiles .......... initializes MAXFiles
ClipX ................. truncates a file
GetPtrBase% ........... returns value set by SetPtrBase
HandleX% .............. returns latest handle opened
SaveLineX ............. allows GetLineX to read multiple files
SetBufferSize ......... controls size of buffer for GetLineX
SetDiskFile ........... (dis/en)ables use of EMS memory
Although the routines in MAXFiles include some support for
networks, they have not been tested in a networked environment.
If you intend to use MAXLIB For PB on a network, you should test
your code thoroughly to ensure it is safe.
The MAXFiles routines described in this section are in two object
files in MAXLIB.PBL, named MAXFILES.OBJ and SHARED.OBJ.
ClearX
-----------------------------------------------------------------
DECLARE SUB ClearX ()
Parameters: none
ClearX may be compared to CLOSE (without parameters) in BASIC,
with one very significant difference. CLOSE closes all open
disk files, but ClearX only closes EMS files. Calling ClearX
has no effect on open disk files. This includes disk files that
were opened as EMS files, but later converted into disk files by
PutX, because of memory limitations.
ClearX
The above code closes all open files currently stored in
expanded memory.
When ClearX is called, it steps through the internal table of
EMS files and systematically calls CloseX to close each of the
files it finds in that table. All the actions described under
CloseX in regard to EMS files also apply to closing EMS files
with ClearX.
Normally, InitMAXFiles registers ClearX with SetOnExit, so that
ClearX will be called automatically as part of your program's
exit code.
SetOnExit is limited to a total of 8 routines that can be
registered in a single program. If your program has already
used all 8 slots prior to calling InitMAXFiles, you should call
ClearX manually before ending your program.
See also CloseX.
ClipX
-----------------------------------------------------------------
DECLARE SUB ClipX (Handle%, NewSize&)
Parameters: Handle% = handle of file to truncate
NewSize& = new size of file, in bytes, as long integer
ClipX lets you truncate an opened file to the size you specify:
ClipX Handle%, 3500&
The above code shortens the file designated by Handle% to a
length of 3500 bytes, assuming the file was more than 3500 bytes
long.
After a call to ClipX the file pointer will point to the first
byte immediately following the new end byte of the file. In the
example above (assuming a zero-based file pointer), the first
byte of the file would be byte zero, the final byte of the file
would be byte 3499 and the pointer would be at byte 3500.
IMPORTANT: If NewSize& is greater than the current size of the
file, ClipX will move the file pointer one byte beyond the
current end byte of the file, but the file will remain the same
size.
If the file designated by Handle% is an EMS file, be aware that
when you call ClipX, any corresponding file on disk will be
truncated at the time of the call to ClipX.
For more information about file pointers, see ABOUT FILE
POINTERS in MAXLIB.DOC.
See also SetLocX.
CloseX
-----------------------------------------------------------------
DECLARE SUB CloseX (Handle%)
Parameters: Handle% = handle of file to close
CloseX is a substitute for CLOSE #FileNum in BASIC. It closes
one file opened by OpenX%.
CloseX Handle%
The above code closes the file designated by Handle%. CloseX
will ignore any attempts to close a handle numbered 0-4. Those
handles are reserved by DOS and closing them would be a mistake.
When Handle% designates an EMS file, CloseX first checks to see
if the file has been altered since it was last opened or flushed
to disk. If the file has been altered, CloseX will open the
corresponding disk file and save the new contents of the file to
disk before closing the file. If the file has not been altered,
the file will not be saved to disk.
Whether or not the file has been altered, CloseX will close
the appropriate entry in the internal table of EMS files and
deallocate the expanded memory occupied by the file, so it can
be used for other purposes.
See also ClearX.
EndX
-----------------------------------------------------------------
DECLARE FUNCTION EndX% ()
Parameters: none
EndX% is a substitute for EOF. It works in conjunction with
GetLineX$ only. When GetLineX$ is processing a text file and
bytes remain to be read, EndX% returns a zero. When GetLineX$
reaches the end of the file and no more bytes remain to be read,
EndX% returns -1.
DO
X% = X% + 1
Array$(X%) = GetLineX$(Handle%)
LOOP UNTIL EndX% OR ErrorCode%
The above code loads a variable length string array with lines
of text from the file designated by Handle%. The loop will
iterate until the end of the file is reached, or an error
occurs.
EndX% will not report the end of a file when a CHR$(26) is
encountered in a file.
See also GetLineX$.
ErrorCode
-----------------------------------------------------------------
DECLARE FUNCTION ErrorCode% ()
Parameters: none
When an error occurs during any of the MAXLIB For PB routines,
the error is trapped (no action is taken by DOS or BASIC) and
the error code is stored in an internal variable. This includes
critical errors. The current contents of that variable are
returned by ErrorCode%.
IF ErrorCode% = 2 THEN PRINT "File not found!"
ErrorCode% may return some non-standard error codes (-1 to -4)
under certain conditions. For more information see HANDLING
ERRORS in MAXLIB.DOC and the file ERRCODE.LST.
See also SetErrorCode.
FlushX
-----------------------------------------------------------------
DECLARE SUB FlushX (Handle%)
Parameters: Handle% = handle of the file to flush to disk
FlushX is a substitute for FLUSH. Calling FlushX ensures that a
complete copy of the file is stored to disk immediately. Files
that are flushed remain open.
If Handle% designates a disk file, FlushX causes the contents of
the file buffers (maintained by DOS) to be written to disk.
If Handle% designates a file stored in expanded memory, FlushX
will open the corresponding disk file, write the contents of the
file to disk and close the disk file. Closing the disk file has
the added effect of flushing the DOS buffers. The EMS file
remains open.
FlushX Handle%
The above code flushes the complete contents of the file
designated by Handle% onto disk.
Flushing is important if you are working with highly valuable
data, because any data that is not fully written to disk is
vulnerable to loss when something disrupts the operation of the
computer running your program.
For more information, see SAFEGUARDING YOUR DATA in MAXLIB.DOC.
See also CloseX.
GetLineX
-----------------------------------------------------------------
DECLARE FUNCTION GetLineX$ (Handle%)
Parameters: Handle% = the handle of the file to read from
GetLineX$ is a substitute for LINE INPUT#. It simplifies the
task of reading ASCII text files one line at time.
TextLine$ = GetLineX$(Handle%)
The above code returns one line of text from the file designated
by Handle%. The line of text starts with the character at the
current file pointer and includes all characters up to but not
including the first carriage return character, or CHR$(13). If
the first character encountered is a CHR$(13), GetLineX$ returns
a null string.
The longest string GetLineX$ may return is 256 bytes. When
GetLineX$ does not encounter a CHR$(13) within the first 256
characters it simply returns those 256 characters.
GetLineX$ allocates a string to use as an internal buffer. The
default size of this buffer is 8174 bytes. When GetLineX$
detects the end of a file, it sets the value reported by EndX%
to -1 and it deallocates its buffer.
If GetLineX$ fails to allocate a string to use as a buffer, it
will return a non-standard error code of -1. One common way for
the buffer allocation to fail is if your code uses the
metacommand $STRING to set a string segment size smaller than
8K. The default buffer size of 8174 bytes requires an 8K string
segment (or larger).
If buffer allocation fails, or if you require a larger or
smaller buffer for other reasons, you may change the size of the
buffer. See SetBufferSize for more details.
Buffering requires GetLineX$ to maintain its own internal
pointer, which will rarely agree with the "regular" file
pointer. For that reason, if you use GetLineX$ to read from
more than one file at once, you may need to use SaveLineX. For
more details, see SaveLineX.
GetLineX$ will not accept a handle for a DOS STDxx device (0-4).
If you call GetLineX$ with such a handle, it will simply return
a null string and report an "invalid handle" error (6).
See also EndX%, GetStX.
GetLocX
-----------------------------------------------------------------
DECLARE FUNCTION GetLocX& (Handle%)
Parameters: Handle% = handle of file in which to find pointer
GetLocX& is a substitute for the function form of SEEK. It
returns a long integer representing the present position of the
file pointer within the file specified by Handle%:
PtrLoc& = GetLocX&(Handle%)
The above code returns the current position of the file pointer
in the file designated by Handle%.
By default, the file is assumed to start at byte 0 (zero). This
default may be changed to start at byte 1 by using the command
SetPtrBase. See SetPtrBase or GetPtrBase for further details.
If an error occurs during a call to GetLocX&, it returns a zero.
Normally, zero is a legal file pointer location. To determine
with certainty whether an error has occured you must call
ErrorCode%.
See also SetLocX.
GetPtrBase
-----------------------------------------------------------------
DECLARE FUNCTION GetPtrBase% ()
Parameters: none
GetPtrBase% returns the base value used by GetLocX& and SetLocX:
Base% = GetPtrBase%
The above code returns the current pointer base value. The
default value is zero, but you may change the value to 1, by
calling SetPtrBase.
Normally, DOS defines the first byte of a file as byte 0 (zero).
However, when Microsoft introduced BINARY file handling into
BASIC, it chose to treat the first byte of a file as byte 1. To
accomodate code written for this convention, MAXFiles includes
the commands SetPtrBase and GetPtrBase%.
When GetPtrBase% returns zero, MAXFiles is acting under the
zero-based (DOS) convention. Under this convention, when the
pointer is at the second byte of a file, GetLocX& will return 1,
and if you want to set the pointer to the second byte you would
use SetLocX 1.
When GetPtrBase% returns 1, MAXFiles is acting under the
one-based (Microsoft BASIC) convention. Under this convention,
when the pointer is at the second byte of a file, GetLocX& will
return 2, and to set the pointer to the second byte you would
use SetLocX 2.
See also SetPtrBase.
GetStX
-----------------------------------------------------------------
DECLARE SUB GetStX (Handle%, ToString AS ANY)
Parameters: Handle% = handle of the file to read from
ToString = string to read data into
GetStX is a substitute for GET$. It lets you read from a file
into a variable length string or flex string. Before calling
GetStX the string must be initialized to the length you want.
The length of the string determines the number of bytes GetStX
will read from the file into the string:
Target$ = SPACE$(100)
GetStX Handle%, Target$
In the above code, 100 bytes would be read from the file
specified by Handle% into Target$. The file would be read
beginning at the current position of the file pointer. GetStX
will advance the file pointer one byte for each byte read.
If you try to read from a file when the file pointer is located
beyond its end, then GetStX will simply return with no action
taken and no error code. If you try to read more bytes than lie
between the pointer and the end byte of the file, GetStX will
read as far as the end byte of the file and stop.
If you want your program to read an ASCII text file (one which
uses a carriage return and linefeed to delimit each line of
text) you will probably want to use GetLineX$, rather than
GetStX.
NOTE: When a parameter is declared AS ANY it must be passed as a
variable. If you pass an equation, constant or literal value,
the compiler will report Error 426: Variable expected.
See also PutStX.
GetX
-----------------------------------------------------------------
DECLARE SUB GetX (Handle%, Bytes&, ToVariable AS ANY)
Parameters: Handle% = the handle of the file to read from
Bytes& = number of bytes to read
ToVariable = the variable to read the data into
GetX resembles GET, but is more powerful. It allows you to read
Bytes& number of bytes from a file into a variable or into an
array. You must specify the handle of the file to read from,
the number of bytes to read, and the variable to read into. If
you are reading into an array, you need to specify the first
element of the range to be read into:
GetX Handle%, 4000&, Arry&(100)
The above example reads 4000 bytes from the file specified by
Handle% into Arry&() starting at element 100.
IMPORTANT: Before using GetX with HUGE arrays, read the section
AVOIDING PROBLEMS WITH HUGE ARRAYS in MAXLIB.DOC.
GetX always reads from the file starting at the position of the
file pointer. GetX will automatically advance the file pointer
one byte forward for each byte it reads. It is up to you to
make certain the file pointer is where you want it to be before
calling GetX.
If you tell GetX to write more bytes than the target variable or
array can hold, it will overwrite whatever lies beyond the end
of your variable or array. If you tell it to write too few
bytes, whatever "garbage" was in that area of RAM won't be fully
overwritten. It is your responsibility to calculate the correct
number of bytes.
If you try to read from a file when the file pointer is located
beyond its end, then GetX will simply return with no action
taken and no error code. If you try to read more bytes than lie
between the pointer and the end byte of the file, GetX will read
as far as the end byte of the file and stop.
If you pass GetX a value in Bytes& less than or equal to zero,
GetX will return without taking any action. No error will be
reported.
GetX can write to both variables or arrays of the following
types: fixed-length strings, numeric variables, and TYPE
variables.
NOTE: When a parameter is declared AS ANY it must be passed as a
variable. If you pass an equation, constant or literal value,
the compiler will report Error 426: Variable expected.
GetX is NOT suitable for reading from files into variable length
strings, flex strings or arrays of such strings. For these
strings you would use GetStX or GetLineX$.
See also PutX.
HandleX
-----------------------------------------------------------------
DECLARE FUNCTION HandleX% ()
Parameters: none
HandleX% returns the handle of the file most recently opened by
OpenX%. Among other things it allows you to use the following
alternate logic when opening a file:
IF OpenX%(FileSpec$) THEN
Handle% = HandleX% 'get the handle for FileSpec$
ELSE
Call ErrorHandler
END IF
It is not recommended that you use HandleX% as a substitute for
a file handle variable.
See also OpenX.
InitMAXFiles
-----------------------------------------------------------------
DECLARE SUB InitMAXFiles ()
Parameters: none
InitMAXFiles must be called once before using any of the other
routines listed in this section. Calling it once is sufficient.
Calling InitMAXFiles more than once in the same program will
have no effect after the first call.
When it is called, InitMAXFiles looks for an EMM driver on the
host computer. If no driver is found, or if a driver is found
with a version number below 4.0, all files subsequently opened
by OpenX% will be ordinary disk files.
If a version 4.0 or greater EMM driver is found, InitMAXFiles
determines how many entries to initialize in an internal table
of EMS files. The maximum number of files MAXFiles can place
into expanded memory at one time is limited to the number of
entries in this table.
When the table of EMS files is full, OpenX% can still open files
as disk files until all available DOS file handles are
exhausted. However, it is important that you always leave at
least one DOS file handle unused, for internal use by MAXFiles.
The default number of entries in this table is 32. If
InitMAXFiles detects fewer than 32 EMS handles free, or fewer
than 32 pages of EMS memory free, the table will be initialized
to hold the smaller of these two values.
Lastly, InitMAXFiles attempts to register ClearX as part of your
program's exit code, using the internal PowerBASIC procedure
called SetOnExit. ClearX deallocates all the expanded memory
that is currently allocated by MAXFiles.
SetOnExit is limited to a total of 8 routines that can be
registered in a single program. If your program has already
used all 8 slots prior to calling InitMAXFiles, you should call
ClearX manually before ending your program.
See also ClearX.
KillX
-----------------------------------------------------------------
DECLARE SUB KillX (FileSpec$)
Parameters: FileSpec$ = name of the file to kill (delete)
KillX is a substitute for KILL. It accepts a file name, which
may be up to 64 characters long and include a drive and
subdirectory path, but not wildcard characters:
FileName$ = "D:\PATH\FILENAME.EXT" 'no wildcards
KillX FileName$ 'delete the file
Do not try to kill a file when it is open. Close it first using
CloseX. If you kill a file when it is open MAXFiles will not
report an error, but you may end up with a mess, possibly
including cross-linked files that must be repaired by the DOS
CHKDSK command.
LoadX
-----------------------------------------------------------------
DECLARE SUB LoadX (Handle%, Bytes&, ToSegment??)
Parameters: Handle% = handle of the file to load data from
Bytes& = number of bytes to load
ToSegment?? = segment at which to load the data
LoadX resembles BLOAD, but is more powerful. Before you can
load a file with LoadX you must open it using OpenX%. You pass
LoadX the handle of an opened file, the number of bytes to load,
and the segment address where you want them loaded. It assumes
an offset of zero.
LoadX Handle%, 4000&, &HB800
The above code loads 4000 bytes from the file designated by
Handle% starting at the address &HB800:0000 (page zero of a
color monitor's video RAM, in text mode).
You may set the file pointer wherever you wish before calling
LoadX, and therefore may read from the file at any point. This
allows you to have more than one screen saved in a single file.
If you try to read from the file when the pointer is located
beyond its end, then LoadX will simply return with no action
taken and no error code. If you try to read more bytes than lie
between the pointer and the end byte of the file, LoadX will
read as far as the end byte of the file and stop.
If the value in Bytes& is less than or equal to zero, LoadX will
return without taking any action. No error will be reported.
Unlike BLOAD, LoadX will not close the file for you. You must
close it using CloseX.
See also SaveX.
OpenX
-----------------------------------------------------------------
DECLARE FUNCTION OpenX% (FileSpec$)
Parameters: FileSpec$ = name of the file to open or create
OpenX% is a substitute for OPEN FOR BINARY. It accepts a
FileName$ up to 64 characters long, which can include a drive
and path, but not wildcard characters. OpenX% opens the file
named and returns the handle that you must use to access that
file, or a zero if there was an error:
FileName$ = "D:\PATH\FILENAME.EXT" 'no wildcards allowed
Handle% = OpenX%(FileName$)
When OpenX% opens a file, it sets the file access code according
to an internal variable. This variable defaults to the code for
read-write access and network compatibility mode, but it may be
changed by making a call to SetAccessCode.
If OpenX% can't find FileName$, it creates a zero-length, normal
attribute file of that name. Created files are opened using the
current access code. This requires OpenX% to create the file
first without the access code, close it and then immediately
reopen it using the access code.
When OpenX% opens a file it must determine whether or not to
store the file in expanded memory. When all of the following
conditions have been met, the file will be stored in EMS:
1) an EMM driver was detected on the host machine, and
2) the EMM driver has a version number of at least 4.0, and
3) a free entry is available in the table of EMS files, and
4) you have not used SetDiskFile to force use of the disk, and
5) sufficient EMS is available to hold the entire file (if
the file is zero-length, one page of EMS must be free).
When OpenX% stores a file in expanded memory, it reads a
complete copy of the file from disk into EMS and closes the disk
file. This frees the DOS handle for further use. Further
changes to the file will be reflected in the copy in EMS, but
will not normally be written to disk until the file is closed or
flushed.
If the file was successfully stored in expanded memory, the
handle returned by OpenX% will be greater than 255. If the file
is not stored in EMS, the handle will be an ordinary DOS file
handle.
Handles returned for files stored in EMS are not the same as
handles issued by the EMM driver. They are created by OpenX%
and refer to entries in an internal table of information
maintained by MAXFiles.
When a file is first opened the file pointer always points to
the first byte of the file. Normally, the first byte is
considered to be byte 0 (zero). MAXFiles also lets you regard
this byte as byte 1. For more information, see SetPtrBase and
GetPtrBase%.
If an error occurs during a call to OpenX%, it returns a zero
rather than a file handle. Zero is a valid handle, but it is
reserved by DOS for STDIN. If OpenX% returns a zero, don't use
it! Instead, call ErrorCode%.
When FileName$ is null or more than 64 characters, then OpenX%
treats these conditions as "file not found" errors.
If FileName$ includes wildcard characters (?*) then your program
will crash! Your program must trap this error before calling
OpenX%.
See also CloseX.
PutStX
-----------------------------------------------------------------
DECLARE SUB PutStX (Handle%, FromString AS ANY)
Parameters: Handle% = handle of the file to write to
FromString = string to write data from
PutStX is a substitute for PUT$. It allows you to write a
variable length string or flex string to a file:
St$ = "This is a test."
PutStX Handle%, St$
The above code writes St$ to the file designated by Handle%.
The string will be written starting at the current position of
the file pointer. PutStX will advance the file pointer one byte
for each byte written.
If the file pointer is anywhere but the end of the file, the
previous contents of the file will be overwritten as PutStX
writes the new bytes to those locations. It is up to you to
make certain the file pointer is pointing where you want it,
before calling PutStX.
If Handle% designates a file stored in expanded memory and not
enough expanded memory can be allocated to allow PutStX to write
the required number of bytes, PutStX will automatically convert
the file from an EMS file to a disk file.
To convert a file from EMS to disk, PutStX must open the
corresponding disk file and write the contents of the file
currently stored in expanded memory to disk. Also, the
corresponding entry in the table of EMS files is cleared and the
expanded memory occupied by the file is deallocated.
IMPORTANT: When converting a file from EMS to disk, PutStX MUST
CHANGE THE HANDLE YOU PASSED IT! If secondary copies of this
handle exist in your program, they must also be changed. Trying
to access the file using the old handle will fail and probably
generate errors.
NOTE: When a parameter is declared AS ANY it must be passed as a
variable. If you pass an equation, constant or literal value,
the compiler will report Error 426: Variable expected.
See also GetStX.
PutX
-----------------------------------------------------------------
DECLARE SUB PutX (Handle%, Bytes&, FromVariable AS ANY)
Parameters: Handle% = the handle of the file to write to
Bytes& = number of bytes to write
FromVariable = the variable to write the data from
PutX resembles PUT, but is more powerful. It allows you to
write Bytes& number of bytes from a variable or an array to a
disk file. You pass PutX the handle of the file to write to,
the number of bytes to write and the variable to be written
from. If you are writing from an array, pass PutX the first
element of the range to be written from:
PutX Handle%, 4000&, Arry&(100)
The above code writes 4000 bytes from Arry&(), starting at
element 100, into the file specified by Handle%. PutX will
write to the file starting at the location of the file pointer.
The file pointer will advance one byte for each byte written.
IMPORTANT: Before using PutX with HUGE arrays, read the section
AVOIDING PROBLEMS WITH HUGE ARRAYS in MAXLIB.DOC.
If the file pointer is anywhere but the end of the file, the
previous contents of the file will be overwritten as PutX writes
the new bytes to those locations. It is up to you to make
certain the file pointer is pointing where you want it, before
calling PutX.
If Handle% designates a file stored in expanded memory and not
enough expanded memory can be allocated to allow PutX to write
the required number of bytes, PutX will automatically convert
the file from an EMS file to a disk file.
To convert a file from EMS to disk, PutX must open the
corresponding disk file and write the contents of the file
currently stored in expanded memory to disk. Also, the
corresponding entry in the internal table of EMS files is
cleared and the expanded memory occupied by the file is
deallocated.
IMPORTANT: When converting a file from EMS to disk, PutX MUST
CHANGE THE HANDLE YOU PASSED IT! If secondary copies of this
handle exist in your program, they must also be changed. Trying
to access the file using the old handle will fail and probably
generate errors.
PutX will ignore any attempt to write zero bytes. This is
because writing zero bytes has the (sometimes traumatic) effect
of truncating a disk file. If you desire this effect, see
ClipX.
If you pass PutX a negative value in Bytes&, PutX will also
ignore it and return without taking action. No error will be
declared.
NOTE: When a parameter is declared AS ANY it must be passed as a
variable. If you pass an equation, constant or literal value,
the compiler will report Error 426: Variable expected.
PutX can write variables or arrays of the following types:
fixed-length strings, numeric variables or TYPE variables.
PutX is NOT suitable for use with variable length strings, flex
strings, or arrays of such strings. Instead, see PutStX.
See also GetX.
SaveLineX
-----------------------------------------------------------------
DECLARE SUB SaveLineX ()
Parameters: none
SaveLineX resets the file pointer of the file most recently read
by GetLineX$ to match the internal file pointer maintained by
GetLineX$. SaveLineX is only needed under the following
conditions:
1) GetLineX$ has not finished reading file A to the end, and
2) you must use GetLineX$ to read from a second file B, and
3) you must return later to file A at the point you left off.
Whenever these three conditions exist, you must call SaveLineX
after your latest read from file A and before reading from file
B, as in the following example:
DO
INCR LineCount%
LineA$ = GetLineX$(A%)
SaveLineX
EndA% = EndX%
LineB$ = GetLineX$(B%)
SaveLineX
EndB% = EndX%
IF LineA$ <> LineB$ THEN
PRINT "Lines"; LineCount%; " in A and B don't match."
END IF
LOOP UNTIL EndA% OR EndB%
SaveLineX always resets the pointer of the file whose handle was
last passed to GetLineX$. If you call SaveLineX prior to your
first call to GetLineX$, it will cause an "invalid handle"
error. If you have closed the file most recently read by
GetLineX$, you will also get the same error.
NOTE: Alternating line-by-line between files, as in the example
above, causes GetLineX$ to repeatedly empty and refill its
buffer, causing it to slow down significantly. It would be much
faster to use GetLineX$ to read each file into its own array and
then to compare the lines afterward.
See also GetLineX.
SaveX
-----------------------------------------------------------------
DECLARE SUB SaveX (Handle%, Bytes&, FromSegment??)
Parameters: Handle% = handle of the file to write to
Bytes& = number of bytes to write
FromSegment?? = segment to save data from
SaveX resembles BSAVE, but is more powerful. It allows you to
read from a memory location, such as video memory, directly into
a file. Notice that SaveX only lets you to pass the segment
portion of the address from which you want data saved. It
assumes an offset of zero.
SaveX Handle%, 4000&, &HB800
In the above code, the 4000 bytes starting at &HB800:0000 (page
zero of a color monitor's video RAM in text mode) will be
written to the file designated by Handle%, starting at the
current position of the file pointer.
Before you can save to a file using SaveX, you must open the
file using OpenX%. Also, SaveX will not close the file for you.
You must close the file seperately, using CloseX, when you are
done with it.
You may use SaveX to write more than 64K bytes at once. Also,
you may append data onto the end of an existing file, so you may
have as many screens full of information as you wish in a single
file.
If Handle% designates a file stored in expanded memory and not
enough expanded memory can be allocated to allow SaveX to write
the required number of bytes, SaveX will automatically convert
the file from an EMS file to a disk file.
To convert a file from EMS to disk, SaveX must open the
corresponding disk file and write the contents of the file
currently stored in expanded memory to disk. Also, the
corrseponding entry in the table of EMS files is cleared and the
expanded memory occupied by the file is deallocated.
IMPORTANT: When converting a file from EMS to disk, SaveX MUST
CHANGE THE HANDLE YOU PASSED IT! If secondary copies of this
handle exist in your program, they must also be changed. Trying
to access the file using the old handle will fail and probably
generate errors.
If the value in Bytes& is less than or equal to zero, SaveX will
return without taking any action. No error will be reported.
SaveX does NOT add a header to your files, as BSAVE does.
See also LoadX.
SetAccessCode
-----------------------------------------------------------------
DECLARE SUB SetAccessCode (AccessCode%)
Parameters: AccessCode% = access code to use in opening files
SetAccessCode sets the file access code used by OpenX% when
opening files:
SetAccessCode 0
Handle% = OpenX%(FileName$)
The above code opens FileName$ with a read-only access code.
This is not the same as giving the file a read-only attribute.
When you set a new access code using SetAccessCode, all
subsequent calls to OpenX% will use the new access code.
These BASIC commands are equivalent to the following access
codes:
ACCESS READ WRITE ... 2
ACCESS READ ....... 0
ACCESS WRITE ....... 1
ACCESS READ SHARED ... 64
LOCK READ ....... 50
LOCK WRITE ....... 34
IMPORTANT: MAXFiles has not been tested in a networked
environment. If you use MAXFiles in a network, you should test
it until you are satisfied it is safe.
For more complete information about access codes, consult a DOS
reference.
SetBufferSize
-----------------------------------------------------------------
DECLARE SUB SetBufferSize (Bytes%)
Parameters: Bytes% = number of bytes to use for buffer
SetBufferSize lets you change the size of the buffer allocated
by GetLineX$. The default buffer size is 8174 bytes.
SetBufferSize 5000
The example above sets the buffer size to 5000 bytes.
If you try to set the buffer size above 32750 bytes or below
1006 bytes, SetBufferSize will round the buffer size up or down
to match the nearest of these limits.
Because the buffer allocated by GetLineX$ is a string, it is
affected by the string segment size set by $STRING. The largest
string that can be allocated within a string segment is the size
of the segment minus 18 bytes.
For example, if the example code above were preceeded by the
metacommand $STRING 4, the buffer of 5000 bytes would not fit
inside the 4K string segment, causing GetLineX$ to fail. You
would need to set the buffer size to between 4078 and 1006 bytes
before your first call to GetLineX$ to compensate for the
$STRING 4 statement.
When GetLineX$ fails to allocate a buffer string, it returns the
non-standard error code -1.
See also GetLineX.
SetDiskFile
-----------------------------------------------------------------
DECLARE SUB SetDiskFile (Switch%)
Parameters: Switch% = non-zero value disables use of EMS
SetDiskFile allows you to control whether OpenX% attempts to use
expanded memory when opening files. By default, OpenX% will
always attempt to open a file as an EMS file first, then fall
back to disk in the event the file could not be opened in EMS.
Calling SetDiskFIle with a non-zero value in Switch% will ensure
that all files opened subsequently by OpenX% will be disk files.
Calling SetDiskFile with a zero value in Switch% re-enables the
use of expanded memory.
%DISK = -1
SetDiskFile %DISK
The above code disables the use of expanded memory by OpenX%.
See also OpenX.
SetErrorCode
-----------------------------------------------------------------
DECLARE SUB SetErrorCode (ErrorCode%)
Parameters: ErrorCode% = value to place into internal error code
SetErrorCode allows you to reset the error code reported by
ErrorCode% to any integer value:
SetErrorCode 2 'set the new error code
PRINT ErrorCode% 'will always print "2"
For more information see HANDLING ERRORS in MAXLIB.DOC.
See also ErrorCode.
SetLocX
-----------------------------------------------------------------
DECLARE SUB SetLocX (Handle%, NewPtrLoc&)
Parameters: Handle% = handle of file whose ptr will be reset
NewPtrLoc& = new location of pointer in the file
SetLocX is a substitute for the statement form of SEEK. You
pass it the handle of the file whose pointer you want to set and
the location of the byte where you want to set the file pointer
(as an offset from the start of the file):
SetLocX Handle%, 9000&
The above code moves the file pointer in the file designated by
Handle% to byte number 9000. If subsequently you were to read
from the file, byte 9000 would be the first byte read. If you
were to write to the file, byte 9000 would be the first byte
written to.
If you are unfamiliar with file pointers, see ABOUT FILE
POINTERS in MAXLIB.DOC.
How SetLocX interprets the value of NewPtrLoc& may vary,
depending on whether you have made a call to SetPtrBase. By
default, MAXFiles considers the first byte of a file to be byte
zero. However, you may change this default to a 1-based system,
using SetPtrBase. Please see SetPtrBase for more details.
It is possible to move the file pointer many bytes beyond the
"end" byte of a disk file. This is a valid position at which to
write to a disk file -- in which case the disk file will be
extended to include all the bytes falling between the previous
"end" of the disk file and the byte where the pointer was
located when the writing was initiated.
IMPORTANT: If the file designated by Handle% is an EMS file
rather than a disk file (EMS files have handles greater than
255) and NewPtrLoc& exceeds the size of the file plus the value
of the pointer base, SetPtrLoc will move the pointer only as far
as the byte immediately following the end byte of the file.
This allows you to move the pointer to the correct byte at which
to append data directly to the end of the file, but no further.
This restriction does not apply to disk files.
If you try to read from a file when the pointer is located
beyond its end, then MAXFiles will simply return with no action
taken and no error code. If you try to read more bytes than lie
between the pointer and the end byte of the file, MAXFiles will
read as far as the end byte of the file and stop.
See also GetLocX.
SetPtrBase
-----------------------------------------------------------------
DECLARE SUB SetPtrBase (PtrBase%)
Parameters: PtrBase% = non-zero value sets pointer base to 1
SetPtrBase sets the base value used by GetLocX& and SetLocX:
SetPtrBase 1 'sets pointer base to 1
Calling SetPtrBase with a zero sets the pointer base to zero.
Calling SetPtrBase with any non-zero value sets the base value
to 1. The default base value is zero.
Normally, DOS defines the first byte of a file as byte 0 (zero).
However, when Microsoft introduced BINARY file handling into
BASIC, it chose to treat the first byte of a file as byte 1. To
accomodate code written for this convention, MAXFiles includes
the commands SetPtrBase and GetPtrBase%.
If you call SetPtrBase with a zero, MAXFiles will act under the
zero-based (DOS) convention. This is also the MAXFiles default.
Under this convention, when the pointer is at the second byte of
a file, GetLocX& will return 1, and if you want to set the
pointer to the second byte you would use SetLocX 1.
If you call SetPtrBase with a non-zero value, MAXFiles will act
under the one-based (Microsoft BASIC) convention. Under this
convention, when the pointer is at the second byte of a file,
GetLocX& will return 2, and to set the pointer to the second
byte you would use SetLocX 2.
See also GetPtrBase.
SizeX
-----------------------------------------------------------------
DECLARE FUNCTION SizeX& (Handle%)
Parameters: Handle% = handle of file whose size you want
SizeX& is a substitute for LOF. It returns the length of a file
that has been opened with OpenX%, as a long integer:
HowBig& = SizeX&(Handle%)
In the above code, SizeX& returns the size of the file
designated by Handle% and assigns the value to the variable
HowBig&.
If an error occurs, SizeX& returns a zero. Since zero is also a
valid file length the only way to determine certainly if an
error has occured is to call ErrorCode%.
********************************************************************
END OF SECTION ONE: MAXFILES
********************************************************************
MAXArray Routines
-----------------------------------------------------------------
MAXArray can be used to create arrays in EMS to hold any
variables having a fixed length. This includes all numeric
variables (such as DOUBLE, LONG or BCD) and TYPE variables. It
also includes fixed-length strings.
Arrays created with MAXArray cannot be used with variable
length strings or flex strings.
MAXArray allows you to create data arrays up to the full amount
of expanded memory available on the host computer. Normally,
the maximum number of arrays MAXArray can dimension at once is
32. This may be lower, if few EMS resources are available.
Except for RedimEMS, all the routines in MAXArray will work
under any EMM driver, starting with v3.0. RedimEMS requires a
v4.0 EMM driver.
The following is a list of the MAXFiles routines that have close
counterparts in PowerBASIC:
DimEMS% ............... DIM
InEMS ................. Array(Index) = Variable
OutEMS ................ Variable = Array(Index)
EraseEMS .............. ERASE
RedimEMS .............. REDIM
LBoundEMS% ............ LBOUND
UBoundEMS% ............ UBOUND
BytesFreeEMS& ......... FRE
ErrorCode% ............ ERR
SetErrorCode .......... ERROR
In addition to these, MAXArray has a number of routines that
have no counterpart in PowerBASIC:
InitMAXArray .......... initializes MAXArray routines
ArrayInEMS ............ copies conventional array to EMS
ArrayOutEMS ........... copies EMS to conventional array
ClearEMS .............. erases/deallocates all EMS arrays
FileInEMS ............. copies file to EMS array
FileOutEMS ............ copies EMS array to file
HandlesEMS% ........... returns number of free array handles
VersionEMS% ........... returns version number of EMM driver
The MAXArray routines described in this section are in two
object files in MAXLIB.PBL, named MAXARRAY.OBJ and SHARED.OBJ.
ArrayInEMS
-----------------------------------------------------------------
DECLARE SUB ArrayInEMS (Handle%, FirstElement AS ANY)
Parameters: Handle% = handle of the EMS array to copy into
FirstElement = first element of array to copy from
This routine copies a conventional array into an array in EMS
memory. Handle% designates the EMS array to copy the data into,
which will normally have the same characteristics and same size
as the conventional array you want to copy from. FirstElement
is generally assumed to be the first element of the conventional
array you want to copy, but that is not required.
IMPORTANT: If the conventional array to be copied into the EMS
array is a HUGE array with an element size which is not a power
of two (not 2,4,8,16...etc.), then you cannot use ArrayInEMS.
Instead, you must copy the array one element at a time in a
loop, using InEMS. See AVOIDING PROBLEMS WITH HUGE ARRAYS in
MAXLIB.DOC for further details.
DIM PBArray (100 TO 350) AS DOUBLE 'create an array of doubles
. 'fill it with data here
.
EMSArray% = DimEMS%(100, 350, 8) 'create a similar EMS array
ArrayInEMS EMSArray%, PBArray(100) 'copy PBArray into EMSArray
The above code dimensions arrays in both conventional memory and
EMS, then copies the conventional array into the EMS array.
In this example, EMSArray% was dimensioned with the same first
index (100) and last index (350) and same element length (8
bytes) as PBArray. This is recommended, but not required.
ArrayInEMS treats the parameter FirstElement purely as the
address in conventional memory from which to start copying as
many bytes as the EMS array was dimensioned to hold.
If the EMS array is smaller than the conventional array, only
part of the conventional array will be copied. If the EMS array
is larger than the conventional array, some excess bytes will be
copied into the final elements of the EMS array from the memory
just beyond the end of the conventional array.
ArrayInEMS will not prevent you from copying a conventional
array into an EMS array having a different element length.
However, the data will probably appear garbled when you try to
access individual elements.
This routine may generate a non-standard error code of -3, if
the EMSHandle% parameter you pass it is an invalid handle.
NOTE: When a parameter is declared AS ANY it must be passed as a
variable. If you pass an equation, constant or literal value,
the compiler will report Error 426: Variable expected.
See also ArrayOutEMS.
ArrayOutEMS
-----------------------------------------------------------------
DECLARE SUB ArrayOutEMS (Handle%, FirstElement AS ANY)
Parameters: Handle% = handle of the EMS array from which to copy
FirstElement = first element of the array to copy into
This routine copies an array from EMS memory into an array in
conventional memory. Handle% designates the EMS array to be
copied. FirstElement is generally assumed to be the first
element of a conventional array having the same characteristics
and size as the EMS array, but this is not strictly required.
IMPORTANT: If the conventional array into which you are copying
the EMS array is a HUGE array with an element size which is not
a power of two (not 2,4,8,16...etc.), then you cannot use
ArrayOutEMS. Instead, you must copy the array one element at a
time, using OutEMS. See AVOIDING PROBLEMS WITH HUGE ARRAYS in
MAXLIB.DOC for further details.
EMSArray% = DimEMS%(100, 350, 8) 'dim array to hold doubles
. 'EMSArray filled with data
.
DIM PBArray (100 TO 350) AS DOUBLE 'dim an array to copy into
ArrayOutEMS EMSArray%, PBArray(100) 'copy EMSArray into PBArray
The above code dimensions arrays in both conventional memory and
EMS, then copies the EMS array into the conventional array.
In this example code, PBArray was dimensioned with the same
first index (100) and last index (350) and same element length
(DOUBLE = 8 bytes) as the array designated by EMSArray%. This
is recommended, but not required.
ArrayOutEMS treats the parameter FirstElement purely as the
address in conventional memory where it will start to copy the
number of bytes the EMS array was dimensioned to hold. If the
EMS array is smaller than the conventional array into which it
will be copied, the excess elements in the conventional array
will retain whatever values they had before calling ArrayOutEMS.
WARNING: If the EMS array you want to copy is larger than the
conventional array into which it will be copied, the excess
bytes from the EMS array will overwrite the memory beyond the
end of the conventional array, corrupting that memory and
probably losing your valuable data.
ArrayOutEMS will not prevent you from copying an EMS array into
a conventional array having a different element length.
However, the data will probably appear garbled when you try to
access individual elements.
This routine may generate a non-standard error code of -3, if
the EMSHandle% parameter you pass it is an invalid handle.
NOTE: When a parameter is declared AS ANY it must be passed as a
variable. If you pass an equation, constant or literal value,
the compiler will report Error 426: Variable expected.
See also ArrayInEMS.
BytesFreeEMS&
-----------------------------------------------------------------
DECLARE FUNCTION BytesFreeEMS& ()
Parameters: none
This routine returns the number of bytes of unallocated EMS
memory, as a long integer.
FreeEMS& = BytesFreeEMS&
The above code returns the number of bytes of unallocated EMS
memory. This is not the same as the number of bytes of EMS
memory installed.
BytesFreeEMS& will return a zero if any of the following
conditions are met:
1) all EMS memory has already been allocated, or
2) no EMS driver is installed, or
3) an error occured, or
4) InitMAXArray was not called before calling BytesFreeEMS&.
The number of bytes of free EMS memory will always be a multiple
of 16384 (16K).
See also HandlesEMS%.
ClearEMS
-----------------------------------------------------------------
DECLARE SUB ClearEMS ()
Parameters: none
This routine erases all EMS arrays currently allocated through
DimEMS. It does this by stepping through an internal table of
array information and deallocating every array it finds there.
ClearEMS will not deallocate EMS memory that was allocated by
other programs, or by calls made directly to the EMM driver.
Only memory allocated by DimEMS or RedimEMS will be deallocated.
The data in arrays cleared by ClearEMS cannot be retrieved, so
be cautious when calling ClearEMS.
Deallocation is important, because (unlike conventional RAM) EMS
memory stays allocated when the program that allocated it ends.
For that reason, if you forget to deallocate EMS memory before
ending your program that EMS memory cannot be used by other
programs.
To help you avoid this problem, InitMAXArray registers ClearEMS
as part of the exit code performed automatically when your
program ends. More details can be found under InitMAXArray.
See also EraseEMS.
DimEMS%
-----------------------------------------------------------------
DECLARE FUNCTION DimEMS% (FirstIndex%, LastIndex%, ElementLen%)
Parameters: FirstIndex% = first element number in array
LastIndex% = last element number in array
ElementLen% = fixed length of each element
This routine allocates an array in EMS memory large enough to
hold the requested number of elements and returns a handle that
your program must use to access that array. The following two
lines of code are comparable:
DIM ArrayName (50:1000) AS STRING * 200 'BASIC array
ArrayName% = DimEMS%(50, 1000, 200) 'EMS array
DimEMS will never return zero as a valid handle for an array,
but DimEMS does return a zero if it fails to dimension an array.
DimEMS may return a zero under any of the following conditions:
1) insufficient EMS memory is available, or
2) no space is available in the table of array info, or
3) no EMM driver was detected by InitMAXArray, or
4) InitMAXArray was not called before calling DimEMS, or
5) an error occured during the allocation of the handle, or
6) the value in ElementLen% was less than or equal to zero.
When DimEMS creates an array, it stores information about that
array in an internal table. The handle returned by DimEMS is
not a "true" EMS handle, but actually refers to a location in
the table where information about an array can be found.
The values of FirstIndex% and LastIndex% are limited to the
range of a signed integer. That range is from -32768 to 32767.
The largest possible size you may designate for an individual
element in an EMS array is 32767 bytes.
If ElementLen% is less than or equal to zero, DimEMS will
generate a non-standard error code of -4 and a handle of zero.
If FirstIndex% is greater than LastIndex%, DimEMS will
automatically correct their order, using LastIndex% as the first
element in the array and FirstIndex% as the last element.
Unlike BASIC, which initializes array elements to zero, the
initial values of the elements in EMS arrays are unpredictable.
EMS memory can only be allocated in multiples of 16K bytes
(known as pages), so DimEMS must allocate the minimum number of
16K pages needed to hold the requested number of elements. For
more information, see ABOUT EXPANDED MEMORY in MAXLIB.DOC.
See also RedimEMS.
EraseEMS
-----------------------------------------------------------------
DECLARE SUB EraseEMS (Handle%)
Parameters: Handle% = handle of EMS array to erase
This routine erases a single array in EMS memory. The array is
designated by Handle%. When an EMS array is erased, the
expanded memory it occupied is freed for further use. EraseEMS
will also remove the entry for Handle% from the internal table
of array information maintained by the MAXArray routines.
EraseEMS Handle%
The above code erases the array designated by Handle%.
The data in an erased array cannot be retrieved. For that
reason you should be cautious when calling EraseEMS.
This routine may generate a non-standard error code of -3, if
the Handle% parameter you pass it is an invalid handle.
See also DimEMS, ClearEMS.
ErrorCode
-----------------------------------------------------------------
DECLARE FUNCTION ErrorCode% ()
Parameters: none
This routine returns the error code stored in an internal
variable. This variable always reports the most recent error
that took place during any call to any MAXLIB For PB routine.
If no error has occured, ErrorCode% returns a zero.
However, if an error does take place, every subsequent call to
ErrorCode% will continue to report the same error until one of
two things happens:
1) another, different error takes place, or
2) your program calls SetErrorCode to reset the error code.
ErrorCode% may return some non-standard error codes (-1 to -4)
under certain conditions. For more information see HANDLING
ERRORS in MAXLIB.DOC and the file ERRCODE.LST.
See also SetErrorCode.
FileInEMS
-----------------------------------------------------------------
DECLARE SUB FileInEMS (DOSHandle%, EMSHandle%)
Parameters: DOSHandle% = DOS handle of the file to copy into array
EMSHandle% = handle of the array to copy file into
This routine is designed to load data from a disk file into an
array in EMS memory. Before calling FileInEMS, you must open
the disk file and get its DOS file handle (which is different
from its file number in BASIC).
FileNum% = FREEFILE
OPEN FileName$ FOR BINARY AS FileNum%
DOSHandle% = FILEATTR(FileNum%, 2) 'FILEATTR gets DOS handle
Records% = LOF(FileNum%) \ RecordLength%
EMSHandle% = DimEMS%(1, Records%, RecordLength%)
FileInEMS DOSHandle%, EMSHandle%
CLOSE FileNum%
The example code above opens a BASIC file, gets its DOS handle,
calculates the number of array elements needed to hold the
entire file (based on a known record length). It then
dimensions an EMS array of the correct size and copies the file
into it using FileInEMS.
FileInEMS writes as many bytes from the file into the EMS array
as the size of the array. Normally, the file and the array you
dimension will be the same size.
If the array size is smaller than the file size, FileInEMS will
write as many bytes into the array as it will hold, then stop
reading from the file. If the array size is larger than the
file size, FileInEMS will write the entire file into the array
and stop, so that the unfilled elements in the array will keep
the values they held before you called FileInEMS.
FileInEMS will read from the file, starting at the current
position of the file pointer. For more information about file
pointers, see the ABOUT FILE POINTERS chapter in MAXLIB.DOC.
FileInEMS requires that the data in the file it is reading has
no gaps or discontinuities. Files saved with FileOutEMS will
meet this requirement. Files saved with PutX from a HUGE array
may not meet this requirement. For details, see AVOIDING
PROBLEMS WITH HUGE ARRAYS in MAXLIB.DOC.
Because FileInEMS accesses a disk drive it includes critical
error trapping. For more information, see HANDLING ERRORS in
MAXLIB.DOC.
This routine may generate a non-standard error code of -3, if
the EMSHandle% parameter you pass it is an invalid handle.
See also FileOutEMS.
FileOutEMS
-----------------------------------------------------------------
DECLARE SUB FileOutEMS (DOSHandle%, EMSHandle%)
Parameters: DOSHandle% = DOS handle of file to copy array into
EMSHandle% = handle of an array to copy into a file
This routine is designed to write data from an EMS array into a
disk file. Before calling FileOutEMS, you must open the file
and get its DOS file handle (which is different from its file
number in BASIC).
EMSHandle% = DimEMS%(1, 1000, 32) 'dim 32000 byte array
.
.
FileNum% = FREEFILE
OPEN FileName$ FOR BINARY AS FileNum%
DOSHandle% = FILEATTR(FileNum%, 2) 'FILEATTR gets DOS handle
FileOutEMS DOSHandle%, EMSHandle% 'write 32000 bytes
CLOSE FileNum%
The example code above dimensions an EMS array, then it opens a
binary file, gets its DOS handle, and copies the EMS array into
it using FileOutEMS. Then it closes the file.
FileOutEMS calculates the number of bytes to write to the file,
based on the size of the array. The entire array will be
written to the file starting at the current position of the file
pointer. If the file pointer is midway into the file, that is
where FileInEMS will start writing. For more information about
file pointers, see ABOUT FILE POINTERS in MAXLIB.DOC.
Because FileOutEMS accesses a disk drive it includes critical
error trapping. If a critical error takes place during a call
to FileOutEMS, the error will be trapped and reported through
ErrorCode%. For more information, see HANDLING ERRORS in
MAXLIB.DOC.
This routine may generate a non-standard error code of -3, if
the EMSHandle% parameter you pass it is an invalid handle.
See also FileInEMS.
HandlesEMS
-----------------------------------------------------------------
DECLARE FUNCTION HandlesEMS% ()
Parameters: none
The number of arrays DimEMS% can dimension at one time is
limited to the number of entries in an internal table of array
information it maintains. HandlesEMS% reports the number of
unused entries in that table.
Each time you dimension an array, the number reported by
HandlesEMS% will decrease by 1. Each time you erase an array
the number reported by HandlesEMS% will increase by 1.
HandlesEMS% will never report a number greater than 32, which is
the largest size table InitMAXArray can initialize.
When HandlesEMS% reports a zero, no handles are available and no
further EMS arrays can dimensioned, even if expanded memory is
available. Both a handle and expanded memory must be available
before DimEMS can dimension an array.
See also BytesFreeEMS&.
InEMS
-----------------------------------------------------------------
DECLARE SUB InEMS (Handle%, ToElement%, FromVariable AS ANY)
Parameters: Handle% = handle of the array holding ToElement%
ToElement% = index of the array element to write to
FromVariable = a variable of same type as the array
This routine writes the contents of the variable FromVariable
into the array element ToElement%. The following snippets of
code are comparable:
DIM MyArray (1:2000) AS LONG 'dim it for long integers
MyArray(1) = LongVal& 'put LongVal& in element 1
MyArray% = DimEMS(1, 2000, 4) 'dim it for long integers
InEMS MyArray%, 1, LongVal& 'put LongVal& in element 1
InEMS assumes FromVariable is of the same length as ToElement.
If FromVariable has fewer bytes than ToElement, some bytes that
lie beyond FromVariable in memory will be written into
ToElement. If FromVariable has more bytes than ToElement, not
all of FromVariable will be written into ToElement.
If you pass a ToElement% which is outside the bounds of the
array designated by Handle%, InEMS will return without taking
any action, and a non-standard error code (-2) will be reported
by your next call to ErrorCode%.
InEMS is not suitable for manipulating variable-length strings
or flex strings. If you try to write such a string, only the
two-byte string handle will be written into EMS memory, not the
string data.
This routine may generate a non-standard error code of -3, if
the Handle% parameter you pass it is an invalid handle.
NOTE: When a parameter is declared AS ANY it must be passed as a
variable. If you pass an equation, constant or literal value,
the compiler will report Error 426: Variable expected.
See also OutEMS, DimEMS.
InitMAXArray
-----------------------------------------------------------------
DECLARE SUB InitMAXArray ()
Parameters: none
This routine initializes all the other routines in MAXArray. It
must be called once, before calling any other routine. One call
to InitMAXArray is enough. Further calls will return with no
action taken.
When called, InitMAXArray looks for an EMM driver on the host
computer. If no EMM driver is found, further calls to MAXArray
routines will return with no action taken.
To find out whether InitMAXArray located an EMM driver, call
VersionEMS% directly after calling InitMAXArray. If no driver
was found, VersionEMS% will return a zero.
If an EMM driver was found, InitMAXArray looks at how many pages
of memory and how many handles are available. If the EMM driver
is prior to version 4.0, the number of handles must be arrived
at through guesswork and may be wrong.
By default, InitMAXArray creates an internal table with 32
entries. This table is where DimEMS will store information
about each array you dimension. The maximum number of EMS
arrays you can dimension at one time is limited to the number of
entries in this internal table. The table will have fewer than
32 entries under the following conditions:
1) InitMAXArray finds fewer than 32 free handles, or
2) it finds fewer than 32 free pages of EMS memory.
In such cases the table will be initialized with only enough
entries to hold the smaller of these two resources.
If you wish to know the size of the table, call HandlesEMS%
immediately after calling InitMAXArray. HandlesEMS% will return
the number of unused entries in the table, as an integer.
Lastly, InitMAXArray calls the internal PowerBASIC routine
called SetOnExit to register ClearEMS as part of your program's
exit code. See ClearEMS for details.
LBoundEMS
-----------------------------------------------------------------
DECLARE FUNCTION LBoundEMS% (Handle%)
Parameters: Handle% = handle of array whose lower bound you want
This routine is like LBOUND in BASIC. It returns the index
number of the first element of the EMS array designated by
Handle%.
FirstElem% = LBoundEMS%(MyArray%)
The above code returns the number of the first element in the
EMS array designated by the handle MyArray%.
This routine may generate a non-standard error code of -3, if
the EMSHandle% parameter you pass it is an invalid handle.
See also UBoundEMS.
OutEMS
-----------------------------------------------------------------
DECLARE SUB OutEMS (ToVariable AS ANY, Handle%, FromElement%)
Parameters: ToVariable = variable of the same type as the array
Handle% = handle of the array holding FromElement%
FromElement% = index of array element to write from
This routine writes the array element FromElement% into the
variable ToVariable. The following two lines of code are
comparable:
LongVal& = MyArray&(1)
OutEMS LongVal&, MyArray%, 1
OutEMS assumes ToVariable is the same length as FromElement. If
ToVariable has more bytes than FromElement, a number of bytes at
the end of ToVariable will be left intact.
WARNING: If ToVariable has fewer bytes than FromElement%, OutEMS
will overwrite some of the bytes that lie beyond ToVariable in
memory, corrupting them and probably losing data.
If you pass a FromElement% which is outside the bounds of the
array designated by Handle%, OutEMS will return without taking
any action, and a non-standard error code (-2) will be reported
by your next call to ErrorCode%.
This routine may generate a non-standard error code of -3, if
the Handle% parameter you pass it is an invalid handle.
NOTE: When a parameter is declared AS ANY it must be passed as a
variable. If you pass an equation, constant or literal value,
the compiler will report Error 426: Variable expected.
See also InEMS, DimEMS.
RedimEMS
-----------------------------------------------------------------
DECLARE SUB RedimEMS (Handle%, LastIndex%)
Parameters: Handle% = handle of the array to redimension
LastIndex% = new last element number in the array
This routine redimensions the array designated by Handle% to the
new size indicated by LastIndex%. The redimensioned array keeps
the same handle, the same first index and the same element
length it had when it was originally dimensioned. If you
require these to change, you must dimension a new array.
LastIndex% may be smaller than or larger than the current last
element number, making the array either smaller or larger. If
the array becomes larger, all the data is preserved. If the
array becomes smaller, all the data up to the new last element
is preserved and data above that point becomes unrecoverable.
Handle% = DimEMS%(1001, 2000, 32) 'dimension 32000 bytes
RedimEMS Handle%, 3000 'redim to 64000 bytes
The above code dimensions an EMS array of 1000 elements, where
the first index is 1001 and the last is 2000. Then it
redimensions it with 2000 elements, where the first index is
1001 and the last is 3000.
RedimEMS requires an EMM driver of v4.0 (or later). If the EMM
driver is v3.x, RedimEMS will return without taking any action.
You can check the EMM version using VersionEMS.
Unlike REDIM in BASIC, you cannot use RedimEMS to dimension an
EMS array that has not been dimensioned. All EMS arrays must be
dimensioned with DimEMS before they can be redimensioned.
If you redimension an array to make it larger, the initial
values in the added elements will be unpredictable.
RedimEMS will generate a non-standard error code of -3, if the
Handle% parameter you pass it is an invalid handle. It will
generate a non-standard error code of -2, if the new LastIndex%
is less than the FirstIndex% of the array.
See also DimEMS, VersionEMS.
SetErrorCode
-----------------------------------------------------------------
DECLARE SUB SetErrorCode (ErrorCode%)
Parameters: ErrorCode% = new value for internal error code
This routine resets MAXLIB's internal error code variable to the
value passed in the ErrorCode% parameter.
SetErrorCode 0
The above code resets the internal error code variable to zero.
For more information on error handling, see HANDLING ERRORS in
MAXLIB.DOC.
See also ErrorCode.
UBoundEMS
-----------------------------------------------------------------
DECLARE FUNCTION UBoundEMS% (Handle%)
Parameters: Handle% = handle of array whose upper bound you want
This routine is like UBOUND in BASIC. It returns the index of
the last element in the EMS array designated by Handle%
LastElem% = UBoundEMS%(MyArray%)
The above code returns the index of the last element in the EMS
array designated by the handle MyArray%.
This routine may generate a non-standard error code of -3, if
the EMSHandle% parameter you pass it is an invalid handle.
See also LBoundEMS%.
VersionEMS
-----------------------------------------------------------------
DECLARE FUNCTION VersionEMS% ()
Parameters: none
This routine returns the version number of the EMM driver, as an
integer. For example, version 4.0 would be returned as 40, and
version 3.2 would be returned as 32. If no EMM driver was
detected by InitMAXArray, VersionEMS% returns a zero.
DriverVer% = VersionEMS%
Except for RedimEMS, all the routines in MAXArray should work
with every version of EMM driver software. RedimEMS requires
version 4.0.
********************************************************************
END OF SECTION TWO: MAXARRAY
********************************************************************